home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.std.c
- Path: nntp.coast.net!torn!sq!msb
- From: msb@sq.com (Mark Brader)
- Subject: Re: Restrictions on qsort compare function?
- Message-ID: <1996Mar21.113301.2622@sq.com>
- Organization: SoftQuad Inc., Toronto, Canada
- References: <4iokop$h4p@lyra.csx.cam.ac.uk> <4iqjar$2m9@usenet.pa.dec.com>
- Date: Thu, 21 Mar 1996 11:33:01 GMT
-
- > > Are there any limitations on what the sort function
-
- It's better to call it a comparison function; qsort() is the sort function.
-
- > > passed over to qsort can do or return?
-
- The standard states
-
- # The function shall return an integer less than, equal to, or greater
- # than zero if the first argument is considered to be respectively
- # less than, equal to, or greater than the second.
-
- In other words, it must yield an ordering of the possible data values.
- This is only the case if
-
- 1. It is a pure function:
- repeated calls to compar(x,y) yield a result having the
- same sign each time
-
- 2. It is antisymmetric (I think that's the right word):
- if compar(x,y) < 0, then compar(y,x) > 0
- if compar(x,y) == 0, then compar(y,x) == 0
- if compar(x,y) > 0, then compar(y,x) < 0
-
- 3. If is transitive:
- if compar(x,y) > 0 && compar(y,z) > 0, then compar(x,z) > 0
-
- > > I know it's meant to return < 0, 0 or > 0 for the various compare
- > > operations, but which you return is purely up to your own comparison
- > > system.
-
- Yes, so long as it obeys *some* comparison system.
-
- > > On tracking down a bug in some old code I noticed that we had the
- > > compare function returning something like "a > b" instead of "b - a".
- >
- > Just one sentence earlier, you gave the exact reason why
- > it doesn't matter if you do "a > b" instead of "a - b".
-
- Of course it matters. With this function, if compar(x,y) > 0, then
- compar(y,x) == 0. This is not antisymmetric.
- it is not a proper comparison function and the behavior is undefined.
-
- > (Actually it can matter: if "a - b" would overflow then doing "a > b"
- > will fix it instead of yielding undefined behavior :-)
-
- Well, "a - b" is indeed unsuitable in general due to potential overflow.
- If the numbers being subtracted are floating-point or are signed integers,
- then arithmetic overflow may occur, causing undefined behavior. It might
- be safe if they are unsigned integers, but then, unless they are narrower
- than int, you run into implementation-defined behavior on converting the
- result of the subtraction to the int that the function returns.
-
- But changing to "a > b", as noted, does not fix it. If simple arithmetic
- comparison is what you want, then you should use something like:
-
- (a > b)? 1: (a < b)? -1: 0
-
- Terser equivalents, but probably considered less clear by most people, are:
-
- (a < b)? -1: (a > b)
- and
- (a > b) - (a < b)
-
- > > My understanding of this is that qsort() ought to be able to handle any
- > > [comparison] function, even if it's something as dumb as (rand()%3)-1.
- >
- > That would not be a [comparison] function (it might even assert that a < b
- > and b < c and c < a).
-
- Right. In fact, it would not necessarily obey any of the three properties
- mentioned above, so the behavior of qsort() would be undefined.
-
- --
- Mark Brader At any rate, C++ != C. Actually, the value of the
- msb@sq.com expression "C++ != C" is [undefined].
- SoftQuad Inc., Toronto -- Peter da Silva
-
- My text in this article is in the public domain.
-